package com.imflea.zero.service.qx.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.imflea.zero.constant.QxContant;
import com.imflea.zero.constants.ZeroContant;
import com.imflea.zero.dto.SearchPageDto;
import com.imflea.zero.exception.BizException;
import com.imflea.zero.model.dao.qx.QxUserInfoMapper;
import com.imflea.zero.model.entity.qx.QxRole;
import com.imflea.zero.model.entity.qx.QxRoleUser;
import com.imflea.zero.model.entity.qx.QxUserInfo;
import com.imflea.zero.model.entity.qx.vo.QxUserInfoVo;
import com.imflea.zero.service.qx.IQxRoleUserService;
import com.imflea.zero.service.qx.IQxUserCertificationService;
import com.imflea.zero.service.qx.IQxUserInfoService;
import com.imflea.zero.util.ZeroCacheUtils;
import com.imflea.zero.util.ZeroJsonUtils;
import com.imflea.zero.util.base.CommonUtils;
import com.imflea.zero.util.base.JsonResult;
import com.imflea.zero.utils.SessionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 管理端客户用户 服务实现类
 * </p>
 *
 * @author xiangbaoyu
 * @since 2021-08-18
 */
@Service
public class QxUserInfoServiceImpl extends ServiceImpl<QxUserInfoMapper, QxUserInfo> implements IQxUserInfoService {
    @Autowired
    private IQxRoleUserService roleUserService;
    @Autowired
    private IQxUserCertificationService userCertificationService;
    @Autowired
    private IQxUserCertificationService certificationService;


    @Override
    public QxUserInfo saveOrUpdateUser(QxUserInfo userInfo) {

        //校验用户名是否已经存在
        //校验用户邮箱是否在系统中已经存在
        //校验用户手机号是否已经存在


        String userId = userInfo.getId();
        boolean result = false;
        if (CommonUtils.isNull(userId)) {
            this.query4AddUser(userInfo);
            userId = CommonUtils.generateRandomString();
            userInfo.setId(userId);
            userInfo.setStatus(QxContant.getUnlockStatus());
            userInfo.setPassword(QxContant.getDefPassword());
            userInfo.setTenantId(SessionUtils.getTenantId());
            result = this.save(userInfo);

            boolean certResult = userCertificationService.saveQxUserCertification(userId, QxContant.getDefPassword(), userId, SessionUtils.getTenantId());
            if (!certResult) {
                throw new BizException("用户创建失败");
            }
        } else {
            result = this.updateById(userInfo);
        }
        if (result) {
            return userInfo;
        } else {
            throw new BizException("用户信息更新失败");
        }

    }

    /**
     * @param userInfo
     * @return boolean
     * @author 祥保玉
     * @description 校验用户名是否已经存在 校验用户邮箱是否在系统中已经存在 校验用户手机号是否已经存在
     * @date 2021/9/23  16:11
     */


    private boolean query4AddUser(QxUserInfo userInfo) {
        String userName = userInfo.getUserName();
        String mobileNum = userInfo.getMobileNum();

        String email = userInfo.getEmail();


        boolean userNameInValid = false;
        boolean mobileNumInValid = false;
        boolean emailInValid = false;

        QueryWrapper<QxUserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name", userName);
        if (!CommonUtils.isNull(mobileNum)) {
            queryWrapper.or().eq("mobile_num", mobileNum);
        }
        if (!CommonUtils.isNull(email)) {
            queryWrapper.or().eq("email", email);
        }
        List<QxUserInfo> result = this.list(queryWrapper);

        if (CommonUtils.isNull(result)) {
            return true;
        } else {
            for (QxUserInfo user : result) {
                String dbUserName = user.getUserName();
                String dbMobileNum = user.getMobileNum();
                String dbEmail = user.getEmail();
                if (userName.equals(dbUserName)) {
                    userNameInValid = true;
                }
                if (!CommonUtils.isNull(mobileNum) && mobileNum.equals(dbMobileNum)) {
                    mobileNumInValid = true;
                }
                if (!CommonUtils.isNull(email) && email.equals(dbEmail)) {
                    emailInValid = true;
                }
            }
        }
        if (userNameInValid || mobileNumInValid || emailInValid) {
            StringBuffer buf = new StringBuffer();
            if (userNameInValid) {
                buf.append("用户名已占用 ");
            }
            if (mobileNumInValid) {
                buf.append(" 手机号已绑定");
            }
            if (emailInValid) {
                buf.append(" 邮箱已绑定");
            }
            buf.append("!");
            throw new BizException(buf.toString());
        }
        return true;

    }


    @Override
    public PageInfo<QxUserInfoVo> queryByTenantId4Page(SearchPageDto req) {
        String tenantId = SessionUtils.getTenantId();
        String searchContent = req.getSearchContent();
        Integer pageIndex = req.getPageNum();
        Integer pageSize = req.getPageSize();
        PageHelper.startPage(pageIndex, pageSize);
        QueryWrapper<QxUserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(wrapper -> wrapper.eq("tenant_id", tenantId));
        if (!CommonUtils.isNull(searchContent)) {
            queryWrapper.and(wrapper -> wrapper.like("user_name", searchContent).or().like("real_name", searchContent));
        }

        List<QxUserInfoVo> userVos = new ArrayList<>();
        List<QxUserInfo> users = this.list(queryWrapper);

        if (CommonUtils.isNull(users)) {
            PageInfo<QxUserInfoVo> pageInfo = new PageInfo<>(userVos);
            return pageInfo;
        }
        PageInfo<QxUserInfo> pUsers = new PageInfo<>(users);
        List<String> userIds = users.stream().map(item -> item.getId()).collect(Collectors.toList());
        Map<String, List<QxRole>> userRolesMap = this.roleUserService.queryAllRoleByUserIds(userIds);
        for (QxUserInfo user : users) {
            QxUserInfoVo vo = new QxUserInfoVo();
            BeanUtil.copyProperties(user, vo);
            if (!CommonUtils.isNull(userRolesMap)) {
                vo.setRoleList(userRolesMap.get(user.getId()));
            }
            userVos.add(vo);
        }
        PageInfo<QxUserInfoVo> pageInfo = new PageInfo<>(userVos);
        pageInfo.setTotal(pUsers.getTotal());
        return pageInfo;
    }

    @Override
    public Boolean updateUserStatusById(String id, String status) {
        UpdateWrapper<QxUserInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("status", status);
        updateWrapper.eq("id", id);
        boolean result = this.update(updateWrapper);
        JsonResult jsonResult = new JsonResult();
        if (result) {
            jsonResult.setInfo(result);
            jsonResult.setCode(ZeroContant.getSuccessCode());
            return result;

        } else {
            throw new BizException("用户状态更新失败");
        }
    }

    @Override
    public Boolean removeUserById(String id) {
        boolean result = this.removeById(id);
        if (result) {
            return result;
        } else {
            throw new BizException("用户状态更新失败");
        }
    }

    @Override
    public Map<String, Object> handleQueryUser4Login(String userName, String password) {
        QueryWrapper<QxUserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name", userName);
        QxUserInfo userInfo = this.getOne(queryWrapper);
        Map<String, Object> token = new HashMap<>();
        if (CommonUtils.isNull(userInfo)) {
            throw new BizException("用户不存在");
        }

        if (QxContant.getLockStauts().equals(userInfo.getStatus())) {
            throw new BizException("账户已经锁定");
        }
        boolean checkPasswordResult = certificationService.query4CheckPassword(userInfo.getId(), password);
        try {
            if (!checkPasswordResult) {
                //登录失败次数
                String logFailTimes = ZeroCacheUtils.getString(QxContant.getLoginFailPool() + userName);
                Integer failTime = 0;
                if (!CommonUtils.isNull(logFailTimes)) {
                    failTime = Integer.valueOf(logFailTimes);
                }
                if (failTime >= 4) {
                    this.updateUserStatusById(userInfo.getId(), QxContant.getLockStauts());
                    ZeroCacheUtils.expire(QxContant.getLoginFailPool() + userName, 1L);
                } else {
                    failTime += 1;
                    ZeroCacheUtils.setString(QxContant.getLoginFailPool() + userName, failTime.toString());
                    ZeroCacheUtils.expire(QxContant.getLoginFailPool() + userName, 1000 * 60 * 60 * 24);
                }
                token.put("msg", "用户密码错误");
                return token;
            } else {
                ZeroCacheUtils.expire(QxContant.getLoginFailPool() + userName, 1L);
            }

        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }


        String accessToken = CommonUtils.generateRandomString();
        token.put("Authorization", accessToken);
        token.put("userName", userName);
        token.put("userId", userInfo.getId());
        token.put("realName", userInfo.getRealName());
        token.put("mobileNum", userInfo.getMobileNum());
        token.put("email", userInfo.getEmail());
        token.put("tenantId", userInfo.getTenantId());

        List<QxRoleUser> qxRoleUsers = roleUserService.queryRolesByUserId(userInfo.getId());

        if (!CommonUtils.isNull(qxRoleUsers)) {
            token.put("roleIds", qxRoleUsers.stream().map(item -> item.getRoleId()).collect(Collectors.toList()));
        } else {
            token.put("roleIds", Collections.emptyList());
        }

        token.put("scope", "");
        try {
            ZeroCacheUtils.setString(QxContant.getLoginTokenPrefix() + accessToken, ZeroJsonUtils.mapToJson(token));
            ZeroCacheUtils.expire(QxContant.getLoginTokenPrefix() + accessToken, QxContant.getSessionTime());
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException(e.getMessage());
        }
        return token;

    }

    /**
     * @param userInfo
     * @return com.imflea.zero.model.entity.qx.QxUserInfo
     * @author 祥保玉
     * @description 租户管理员创建用户，同时为该用户设置角色：商户业务员
     * @date 2021/9/18  17:11
     */


    @Override
    public QxUserInfo saveOrUpdateUser4Tenant(QxUserInfo userInfo) {

/*        String tenantId = userInfo.getTenantId();
        if (CommonUtils.isNull(tenantId)) {
            throw new BizException("请选择租户");
        }*/
        //校验用户名是否已经存在
        //校验用户邮箱是否在系统中已经存在
        //校验用户手机号是否已经存在

        String tenantId = userInfo.getTenantId();
        if (CommonUtils.isNull(tenantId)) {
            tenantId = SessionUtils.getTenantId();
        }
        String userId = userInfo.getId();
        boolean result = false;
        if (CommonUtils.isNull(userId)) {
            this.query4AddUser(userInfo);
            userId = CommonUtils.generateRandomString();
            userInfo.setId(userId);
            userInfo.setTenantId(tenantId);
            userInfo.setStatus(QxContant.getUnlockStatus());
            userInfo.setPassword(QxContant.getDefPassword());
            result = this.save(userInfo);
            if (!result) {
                throw new BizException("创建用户失败");
            }
            boolean certResult = userCertificationService.saveQxUserCertification(userId, QxContant.getDefPassword(), userId, tenantId);
            if (!certResult) {
                throw new BizException("用户创建失败");
            }
            List<String> roleIds = new ArrayList<>();
            boolean isTenantAdmin = roleUserService.query4CheckIsTenantAdmin(SessionUtils.getUserId());
            if (isTenantAdmin) {
                roleIds.add(QxContant.getTenantBuinessRoleId());
                result = roleUserService.saveRoleUserBatch(userId, roleIds, tenantId);
                if (!result) {
                    throw new BizException("创建用户失败");
                }
            } else {
                roleIds.add(QxContant.getTenantAdminRoleId());
                result = roleUserService.saveRoleUserBatch(userId, roleIds, tenantId);
                if (!result) {
                    throw new BizException("创建用户失败");
                }
            }

        } else {
            result = this.updateById(userInfo);
        }
        if (result) {
            return userInfo;

        } else {
            throw new BizException("用户信息更新失败");
        }
    }

    @Override
    public QxUserInfo queryById(String id) {
        QxUserInfo userInfo = this.getById(id);
        return userInfo;
    }

    @Override
    public Boolean updateUserPassword(String newPassword, String oldPassword) {
        String userId = SessionUtils.getUserId();
        QxUserInfo user = this.getById(userId);
        if (CommonUtils.isNull(user)) {
            throw new BizException("您已经被系统冻结,无法修改密码");
        }
        String userStatus = user.getStatus();

        if (!QxContant.getUnlockStatus().equals(userStatus)) {
            throw new BizException("您已经被系统冻结,无法修改密码");
        }
        boolean checkResult = certificationService.query4CheckPassword(userId, oldPassword);
        if (!checkResult) {
            throw new BizException("旧密码错误");
        } else {
            boolean result = certificationService.updateQxUserCertification(newPassword, userId);
            if (!result) {
                throw new BizException("密码修改失败");
            }
        }
        return true;
    }

    @Override
    public boolean updatePassword2Def(String id) {
        boolean result = certificationService.updateQxUserCertification(QxContant.getDefPassword(), id);
        return result;
    }

    @Override
    public boolean updatePasswordBatch() {
        List<QxUserInfo> users = this.list();
        for (QxUserInfo user : users) {
            String salt = CommonUtils.generateRandomString();
            String userPass = user.getPassword();
            String userId = user.getId();
            String tenantId = user.getTenantId();
            boolean result = certificationService.saveQxUserCertification(salt, userPass, userId, tenantId);
            if (!result) {
                throw new BizException("失败了");
            }
        }
        return true;
    }

    @Override
    public List<QxUserInfoVo> queryAllTenantUsers() {
        String tenantId = SessionUtils.getTenantId();


        QueryWrapper<QxUserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(wrapper -> wrapper.eq("tenant_id", tenantId));


        List<QxUserInfoVo> userVos = new ArrayList<>();
        List<QxUserInfo> users = this.list(queryWrapper);


        List<String> userIds = users.stream().map(item -> item.getId()).collect(Collectors.toList());
        Map<String, List<QxRole>> userRolesMap = this.roleUserService.queryAllRoleByUserIds(userIds);
        for (QxUserInfo user : users) {
            QxUserInfoVo vo = new QxUserInfoVo();
            BeanUtil.copyProperties(user, vo);
            if (!CommonUtils.isNull(userRolesMap)) {
                vo.setRoleList(userRolesMap.get(user.getId()));
            }
            userVos.add(vo);
        }

        return userVos;
    }
}
